package com.hoapital.outpbillwork.function.setValue;

import com.hoapital.outpbillwork.module.entity.*;
import com.hoapital.outpbillwork.module.mapper.LabTestMasterMapper;
import com.hospital.common.core.constants.AllFinalValueUtils;
import com.hospital.common.core.hl7Model.hospitalWork.BATCH;
import com.hospital.common.core.hl7Model.hospitalWork.ExamHl7Order;
import com.hospital.common.core.hl7Model.hospitalWork.LabHl7Order;
import com.hospital.common.core.hl7Model.hospitalWork.PrescHl7Order;
import com.hospital.common.core.hl7Model.messages.*;
import com.hospital.common.core.hl7Model.segments.OM_ALL;
import com.hospital.common.core.utils.DateUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author lvyao
 * @description 业务消息体设置值方法
 * @date 2022/6/21
 */
@Service
@Slf4j
@Data
public class SetFunctionHL7 {

    /**
     * 检查\检验\处方消息
     *
     * @param outpMedrec
     * @param outpOrderDescTempList
     * @param objectMaster
     * @param objectDetail
     * @param hosCode
     * @param hosName
     * @param outpOrInp
     * @param patientInfo
     * @param orc1
     * @param orc5
     * @param labTestMasterMapper
     * @return
     */
    public static BATCH packageOmallMessage(OutpMedrec outpMedrec, List<OutpOrderDescTemp> outpOrderDescTempList,
                                            List<Object> objectMaster, List<Object> objectDetail
            , String hosCode, String hosName, String outpOrInp, PatientInfo patientInfo, String orc1, String orc5,
                                            LabTestMasterMapper labTestMasterMapper, String workType, String toApp, String event, String eventType) {
        BATCH batch = new BATCH();
        batch.setType(workType);
        OM_ALL om_all = new OM_ALL();
        CompletableFuture[] completableFutures = new CompletableFuture[7];
        //给信息头
        completableFutures[0] = CompletableFuture.runAsync(
                () -> {
                    MSH msh = SetLabHl7Value.getMsh(AllFinalValueUtils.MESSAGE_FROM, toApp,
                            event, eventType, hosCode, hosName, labTestMasterMapper.getGuid());
                    om_all.setMSH(msh);
                }
        );
        //给患者基本信息
        completableFutures[1] = CompletableFuture.runAsync(
                () -> {
                    patientInfo.setNationCode(labTestMasterMapper.getNationCode(patientInfo.getNation()));
                    patientInfo.setCountryName(labTestMasterMapper.getCountryName(patientInfo.getCitizenship()));
                    patientInfo.setBitthPlace(labTestMasterMapper.getBitthPlace(patientInfo.getBirthPlace()));
                    PID pid = SetLabHl7Value.getPid(patientInfo);
                    om_all.setPID(pid);
                }
        );
        //给患者住院信息
        completableFutures[2] = CompletableFuture.runAsync(
                () -> {
                    PV1 pv1 = SetLabHl7Value.getPV1(String.valueOf(outpMedrec.getOutpId()), outpOrInp, "", "", ""
                            , "", "", outpMedrec.getDocNo(), outpMedrec.getDoctor(), "", "", ""
                            , "", "", new SimpleDateFormat("yyyyMMddHHmmss").format(outpMedrec.getVisitDate()), "", ""
                            , "","");
                    om_all.setPV1(pv1);
                }
        );
        completableFutures[3] = CompletableFuture.runAsync(
                () -> {
                    switch (workType) {
                        case AllFinalValueUtils.EXAM:
                            List<ExamItems> examItemsList = new ArrayList<>();
                            List<ExamHl7Order> examHl7OrderList = new ArrayList<>();
                            //给检验主记录信息以及项目信息
                            for (OutpOrderDescTemp outpOrderDescTemp : outpOrderDescTempList) {
                                ExamHl7Order examHl7Order = new ExamHl7Order();
                                ExamAppoints examAppoints = (ExamAppoints) objectMaster.get(outpOrderDescTempList.indexOf(outpOrderDescTemp));
                                ORC orc = SetLabHl7Value.getORC(String.valueOf(outpOrderDescTemp.getVisitNo()), outpOrderDescTemp.getUserId(), outpOrderDescTemp.getOrderedByDoctor(),
                                        outpOrderDescTemp.getOrderedByDept(), hosCode, hosName, new SimpleDateFormat("yyyyMMddHHmmss").format(outpMedrec.getVisitDate()), orc1, orc5);
                                outpOrderDescTemp.setOrderedByDeptName(labTestMasterMapper.getDeptName(outpOrderDescTemp.getOrderedByDept()));
                                examAppoints.setPerformedByName(labTestMasterMapper.getDeptName(examAppoints.getPerformedBy()));
                                for (Object o : objectDetail) {
                                    ExamItems examItems = (ExamItems) o;
                                    examItemsList.add(examItems);
                                }
                                ExamMaster examMaster = new ExamMaster();
                                BeanUtils.copyProperties(examAppoints, examMaster);
                                examMaster.setReqDeptName(labTestMasterMapper.getDeptName(examMaster.getReqDept()));
                                examMaster.setPerformedByName(labTestMasterMapper.getDeptName(examMaster.getPerformedBy()));
                                examMaster.setReqPhysicianCode(labTestMasterMapper.getUserIdByName(examMaster.getReqPhysician(),examMaster.getReqDept()));
                                OBR obr = SetLabHl7Value.getExamObr(examMaster, outpOrderDescTemp.getUserId(), outpOrderDescTemp.getOrderedByDoctor(),
                                        outpOrderDescTemp.getOrderedByDept(), outpOrderDescTemp.getOrderedByDeptName(), examItemsList);
                                examHl7Order.setORC(orc);
                                examHl7Order.setOBR(obr);
                                examHl7OrderList.add(examHl7Order);
                            }
                            om_all.setExamHl7OrderList(examHl7OrderList);
                            break;
                        case AllFinalValueUtils.TEST:
                            List<LabHl7Order> labHl7OrderList = new ArrayList<>();
                            //给检验主记录信息以及项目信息
                            for (OutpOrderDescTemp outpOrderDescTemp : outpOrderDescTempList) {
                                LabTestMaster labTestMaster = (LabTestMaster) objectMaster.get(outpOrderDescTempList.indexOf(outpOrderDescTemp));
                                LabHl7Order labHl7Order = new LabHl7Order();
                                ORC orc = SetLabHl7Value.getORC(String.valueOf(outpOrderDescTemp.getVisitNo()), outpOrderDescTemp.getUserId(), outpOrderDescTemp.getOrderedByDoctor(),
                                        outpOrderDescTemp.getOrderedByDept(),
                                        hosCode, hosName, new SimpleDateFormat("yyyyMMddHHmmss").format(outpMedrec.getVisitDate()), orc1, orc5);
                                outpOrderDescTemp.setOrderedByDeptName(labTestMasterMapper.getDeptName(outpOrderDescTemp.getOrderedByDept()));
                                labTestMaster.setPerformedByName(labTestMasterMapper.getDeptName(labTestMaster.getPerformedBy()));
                                List<OBR> obrList = new ArrayList<>();
                                for (Object object : objectDetail) {
                                    LabTestItems labTestItems = (LabTestItems) object;
                                    labTestItems.setItemNo(objectDetail.indexOf(labTestItems) + 1);
                                    labTestItems.setSubLabDept(labTestMasterMapper.getSubLabDept(labTestItems.getItemCode()) == null ? "" :
                                            labTestMasterMapper.getSubLabDept(labTestItems.getItemCode()));
                                    OBR obr = SetLabHl7Value.getOBR(labTestMaster, outpOrderDescTemp.getUserId(), outpOrderDescTemp.getOrderedByDoctor(),
                                            outpOrderDescTemp.getOrderedByDept(), outpOrderDescTemp.getOrderedByDeptName(), labTestItems);
                                    obrList.add(obr);
                                }
                                labHl7Order.setORC(orc);
                                labHl7Order.setOBR(obrList);
                                labHl7OrderList.add(labHl7Order);
                            }
                            om_all.setLabHl7Orders(labHl7OrderList);
                            break;
                        case AllFinalValueUtils.EAST_DRUG:
                            om_all.setAL1(new AL1());
                            List<PrescHl7Order> prescHl7OrderList = new ArrayList<>();
                            OutpDoctorPrescMaster outpDoctorPrescMaster =null;
                            try {
                                List<OutpDoctorPrescMaster> objectMaster1 = (List<OutpDoctorPrescMaster>) objectMaster.get(0);
                                outpDoctorPrescMaster = (OutpDoctorPrescMaster) objectMaster1.get(0);
                            }catch (ClassCastException e){
                                outpDoctorPrescMaster = (OutpDoctorPrescMaster) objectMaster.get(0);
                            }
                            outpDoctorPrescMaster.setOrderedByName(labTestMasterMapper.getDeptName(outpDoctorPrescMaster.getOrderedBy()));
                            ORC orc = SetPrescHl7Value.getORC(outpDoctorPrescMaster, hosCode, hosName, orc1, orc5, labTestMasterMapper.getDeptName(outpDoctorPrescMaster.getOrderedBy()));
                            om_all.setORC(orc);
                            //给检验主记录信息以及项目信息
                            for (Object o : objectDetail) {
                                OutpDoctorPrescItems outpDoctorPrescItems = (OutpDoctorPrescItems) o;
                                PrescHl7Order prescHl7Order = new PrescHl7Order();
                                outpDoctorPrescItems.setAdministrationCode(labTestMasterMapper.getAdministrationCode(outpDoctorPrescItems.getAdministration()));
                                String drugForm = labTestMasterMapper.getDrugForm(outpDoctorPrescItems.getPhamCode());
                                outpDoctorPrescItems.setDrugFormCode(drugForm == null ? "" : drugForm.split(",")[0]);
                                outpDoctorPrescItems.setDrugForm(drugForm == null ? "" : drugForm.split(",")[1]);
                                RXR rxr = SetPrescHl7Value.getRxr(outpDoctorPrescItems, outpDoctorPrescMaster);
                                RXO rxo = SetPrescHl7Value.getRxo(outpDoctorPrescItems, outpDoctorPrescMaster);
                                outpDoctorPrescItems.setNationalInsuranceCode(labTestMasterMapper.getinsuranceCode(outpDoctorPrescItems.getPhamCode(), outpDoctorPrescItems.getPhamSpec(), outpDoctorPrescItems.getUnits(), outpDoctorPrescItems.getFirmId()));
                                prescHl7Order.setRXR(rxr);
                                prescHl7Order.setRXO(rxo);
                                prescHl7OrderList.add(prescHl7Order);
                            }
                            AL1 al1 = SetPrescHl7Value.getAl1();
                            om_all.setAL1(al1);
                            om_all.setPrescHl7Orders(prescHl7OrderList);
                            break;
                        case AllFinalValueUtils.WEST_DRUG:
                            break;
                        default:
                    }
                }
        );
        //给诊断信息
        completableFutures[4] = CompletableFuture.runAsync(
                () -> {
                    DG1 dg1 = SetLabHl7Value.getDG1("", outpMedrec.getDiagCode(), outpMedrec.getResult(),
                            outpMedrec.getPhysical(), new SimpleDateFormat("yyyyMMddHHmmss").format(outpMedrec.getVisitDate()),
                            "", "", outpMedrec.getDocNo(), outpMedrec.getDoctor(),outpMedrec.getDept(),outpMedrec.getDeptName(),
                            outpMedrec.getNotes(),outpMedrec.getPatientCondition(),outpMedrec.getMemo(),outpMedrec.getPresentIllness(),outpMedrec.getPastIllness(),
                            outpMedrec.getAuxExamResults(),outpMedrec.getSymptom() );
                    om_all.setDG1(dg1);
                }
        );
//操作信息
        completableFutures[5] = CompletableFuture.runAsync(
                () -> {
                    if (outpOrderDescTempList.size()!=0&&workType.equals(AllFinalValueUtils.EAST_DRUG)) {
                        EVN evn = SetCommSegmentsValue.getEvn(eventType, "", DateUtil.dateToStr(outpOrderDescTempList.get(0).getVisitDate(), "yyyyMMddHHmmss"),
                                outpOrderDescTempList.get(0).getOperatorNo(),
                                outpOrderDescTempList.get(0).getOrderedByDoctor(),
                                outpOrderDescTempList.get(0).getOrderedByDept(), outpOrderDescTempList.get(0).getOrderedByDeptName());
                         om_all.setEVN(evn);
                    }
                }
        );
        //联系人
        completableFutures[6] = CompletableFuture.runAsync(
                () -> {
                    if (event.equals(AllFinalValueUtils.MESSAGE_EVENT_PAT_VISIT)) {
                        NK1 nk1 = SetCommSegmentsValue.getNk1(patientInfo);
                        om_all.setNK1(nk1);
                    }
                }
        );
        CompletableFuture.allOf(completableFutures).join();
        batch.setOM_ALL(om_all);
        return batch;
    }


    /**
     * 医嘱消息封装 暂未写完
     *
     * @return
     */
    public static BATCH packageInpOrderMessage(OutpMedrec outpMedrec, List<OutpOrderDescTemp> outpOrderDescTempList, List<Object> labTestMasterList,
                                               List<Object> objectDetail, String hosCode, String hosName, String outpOrInp,
                                               PatientInfo patientInfo, String orc1, String orc5, LabTestMasterMapper labTestMasterMapper) {
        BATCH batch = new BATCH();
        batch.setType(AllFinalValueUtils.INP_ORM);
        OM_ALL oml_o21 = new OM_ALL();
        //给信息头
        MSH msh = SetLabHl7Value.getMsh(AllFinalValueUtils.MESSAGE_FROM, AllFinalValueUtils.MESSAGE_FROM_PUBLIC,
                AllFinalValueUtils.MESSAGE_EVENT_ORDER, AllFinalValueUtils.MESSAGE_EVENT_NAME_ORDER, hosCode,
                hosName, labTestMasterMapper.getGuid());
        oml_o21.setMSH(msh);
        //给患者基本信息
        patientInfo.setNationCode(labTestMasterMapper.getNationCode(patientInfo.getNation()));
        patientInfo.setCountryName(labTestMasterMapper.getCountryName(patientInfo.getCitizenship()));
        patientInfo.setBitthPlace(labTestMasterMapper.getBitthPlace(patientInfo.getBirthPlace()));
        PID pid = SetLabHl7Value.getPid(patientInfo);
        oml_o21.setPID(pid);

        //给患者住院信息
        PV1 pv1 = SetLabHl7Value.getPV1(String.valueOf(outpMedrec.getOutpId()), outpOrInp, "", "", ""
                , "", "", outpMedrec.getDocNo(), outpMedrec.getDoctor(), "", "", ""
                , "", "", "", "", ""
                , "","");
        oml_o21.setPV1(pv1);

        List<LabHl7Order> labHl7OrderList = new ArrayList<>();
        //给检验主记录信息以及项目信息
        for (OutpOrderDescTemp outpOrderDescTemp : outpOrderDescTempList) {
            LabTestMaster labTestMaster = (LabTestMaster) labTestMasterList.get(outpOrderDescTempList.indexOf(outpOrderDescTemp));
            LabHl7Order labHl7Order = new LabHl7Order();
            ORC orc = SetLabHl7Value.getORC(String.valueOf(outpOrderDescTemp.getVisitNo()), outpOrderDescTemp.getUserId(), outpOrderDescTemp.getOrderedByDoctor(),
                    outpOrderDescTemp.getOrderedByDept(), hosCode, hosName, new SimpleDateFormat("yyyyMMddHHmmss").format(outpMedrec.getVisitDate()),
                    orc1, orc5);
            outpOrderDescTemp.setOrderedByDeptName(labTestMasterMapper.getDeptName(outpOrderDescTemp.getOrderedByDept()));
            labTestMaster.setPerformedByName(labTestMasterMapper.getDeptName(labTestMaster.getPerformedBy()));

            List<OBR> obrList = new ArrayList<>();

            for (Object object : objectDetail) {
                LabTestItems labTestItems = (LabTestItems) object;
                labTestItems.setItemNo(objectDetail.indexOf(labTestItems) + 1);
                labTestItems.setSubLabDept(labTestMasterMapper.getSubLabDept(labTestItems.getItemCode()) == null ? "" :
                        labTestMasterMapper.getSubLabDept(labTestItems.getItemCode()));
                OBR obr = SetLabHl7Value.getOBR(labTestMaster, outpOrderDescTemp.getUserId(), outpOrderDescTemp.getOrderedByDoctor(),
                        outpOrderDescTemp.getOrderedByDept(), outpOrderDescTemp.getOrderedByDeptName(), labTestItems);
                obrList.add(obr);
            }
            labHl7Order.setORC(orc);
            labHl7Order.setOBR(obrList);
            labHl7OrderList.add(labHl7Order);
        }
        oml_o21.setLabHl7Orders(labHl7OrderList);
        //给诊断信息
        DG1 dg1 = SetLabHl7Value.getDG1("2", outpMedrec.getDiagCode(), outpMedrec.getDiagname(),
                outpMedrec.getPhysical(), new SimpleDateFormat("yyyyMMddHHmmss").format(outpMedrec.getVisitDate()),
                "初步诊断", "", "", outpMedrec.getDoctor(),"","","","",
                "","","","","");
        oml_o21.setDG1(dg1);

        batch.setOM_ALL(oml_o21);
        return batch;
    }


}
